package com.ruding.disruptor.utils;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSString;
import org.apache.pdfbox.pdfparser.PDFStreamParser;
import org.apache.pdfbox.pdfwriter.ContentStreamWriter;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDStream;
import org.apache.pdfbox.util.PDFOperator;

public class PdfUtils {
	/**
     * 替换指定pdf文件的文字内容
     * @param args
     */
    public static void replaceContent(){
        //创建一个文档对象
        PDDocument doc =null;
        try {
            //加载文件
            doc =PDDocument.load(new File("C:\\Users\\520878\\Desktop\\CgsMMFyTVK2AFXpdAA0UsiYU4QA689.pdf"));
            System.out.println(doc.isEncrypted());
            //获取全部页数
            List pages= doc.getDocumentCatalog().getAllPages();
            //获取与i对应的页面
            PDPage page = (PDPage)pages.get(0);
            //流对象来接收当前page的内容
            PDStream contents = page.getContents();
            //PDF流对象剖析器(这将解析一个PDF字节流并提取操作数,等等)
            PDFStreamParser parser =new PDFStreamParser(contents.getStream());
            //这将分析流中的标记
            parser.parse();
            //用list存流中的所有标记
            List tokens =parser.getTokens();
            for (int j = 0; j < tokens.size(); j++) {
                //创建一个object对象去接收标记
                Object next = tokens.get( j );
                //instanceof判断其左边对象是否为其右边类的实例
                if(next  instanceof PDFOperator ) {
                    //pdf操作器对象
                    PDFOperator op =(PDFOperator)next;
                    //TJ和TJ是显示的两个操作符。 
                    //PDF中的字符串 
                    if(op.getOperation().equals("Tj")){
                        //COSString对象>>创建java字符串的一个新的文本字符串。
                        COSString previous = (COSString)tokens.get( j-1 );
                        //将此字符串的内容作为PDF文本字符串返回。 
                        String string=previous.getString();
                        //replaceFirst>>替换第一个字符
                        string = string.replaceFirst("深圳", "XXX");
                        System.out.println(string);                           
                        System.out.println(string.getBytes("GBK"));
                        //重置COSString对象
                        previous.reset();
                        //设置字符编码格式
                        previous.append(string.getBytes("GBK") );
                    }else if(op.getOperation().equals("TJ")){
                        //COSArray是pdfbase对象数组,作为PDF文档的一部分
                        COSArray previous  =(COSArray)tokens.get( j-1 );
                        //循环previous
                        for (int k = 0; k < previous.size(); k++) {
                            //这将从数组中获取一个对象,这将取消引用该对象
                            //如果对象为cosnull，则返回null
                            Object arrElement = previous.getObject( k );
                            if( arrElement instanceof COSString ){
                                //COSString对象>>创建java字符串的一个新的文本字符串。
                                COSString cosString =(COSString)arrElement;
                                //将此字符串的内容作为PDF文本字符串返回。 
                                String string =cosString.getString();
                                System.out.println(new String(cosString.getBytes(),"UTF-32"));
                                //替换
                                string = string.replaceFirst("深", "XXX");
                                //重置COSString对象
                                cosString.reset();
                                //设置字符编码格式
                                cosString.append(string.getBytes("GBK") );
                            }
                        }
                    }
                }
            }
             //创建一个PDStream 流对象
             PDStream updatedStream = new PDStream(doc);
             //创建一个输出流接收updatedStream
             OutputStream out =updatedStream.createOutputStream();
             //将接受一个列表并写出它们的流。 
             ContentStreamWriter tokenWriter  =new ContentStreamWriter(out);
             //写入一系列标记，后面跟着一行新行
             tokenWriter.writeTokens(tokens);
             //当前页设置新的内容
             page.setContents( updatedStream );
            //修改后保存的路径
            doc.save("C:\\Users\\520878\\Desktop\\C22.pdf");
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if( doc != null ){
                //关闭文档
                try {
					doc.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
            }
        }
    }
    
    public static void main(String[] args) {
    	replaceContent();
	}
}
